﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using C4F.DevKit.Calendar.Parser;
using C4F.DevKit.Contacts;

namespace C4F.DevKit.Calendar
{
    /// <summary>
    /// A class which combines most of the Calendar API functionality into a single class,
    /// so that the features can all be accessed from a single place.
    /// </summary>
    public class CalendarManager
    {
        #region Properties

        /// <summary>
        /// The folder where Windows stores its calendar files by default.
        /// </summary>
        public string WindowCalendarFolderPath
        {
            get
            {
                string dir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"Microsoft\Windows Calendar\Calendars");
                if (!string.IsNullOrEmpty(dir) && Directory.Exists(dir))
                    return dir;
                else
                    return string.Empty;                
            }
        }

        #endregion Properties

        #region Public Methods

        /// <summary>
        /// Creates a new calendar.
        /// </summary>
        /// <param name="filePath">The file in which to save the calendar.</param>
        public void CreateCalendar(string filePath)
        {
            Writer.CreateCalendar(new List<Appointment>(), filePath);
        }

        /// <summary>
        /// Retrieves all appointments from the specified calendar.
        /// </summary>
        /// <param name="file">The path of the calendar file from which to get
        /// appointments.</param>
        /// <returns>A collection of the appointments from the specified calendar.</returns>
        public IEnumerable<Appointment> GetAllAppointments(string file)
        {
            return Reader.ReadCalendar(file);
        }

        /// <summary>
        /// Retrieves all appointments from the specified calendar, optionally looking in
        /// the default Windows Calendar folder path.
        /// </summary>
        /// <param name="useWindowCalendarFolderPath">Whether or not to look for the file in the
        /// folder Windows Calendar stores files in by default</param>
        /// <param name="fileName">If useWindowsCalendarFolderPath is true, this is just the base name
        /// of the file to use. Otherwise, it is the full path of the file.</param>
        /// <returns>A collection of the appointments from the specified calendar.</returns>
        public IEnumerable<Appointment> GetAllAppointments(bool useWindowCalendarFolderPath, string fileName)
        {
            if (!useWindowCalendarFolderPath)
            {
                return GetAllAppointments(fileName);
            }

            string filePath = Path.Combine(WindowCalendarFolderPath, fileName);

            if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
                throw new FileNotFoundException(string.Format("Could not find the specified calendar file {0}.", fileName));

            return GetAllAppointments(filePath);            
        }

        /// <summary>
        /// Adds appointments to a specified calendar.
        /// </summary>
        /// <param name="filePath">The path of the calendar file to which to add the appointments.</param>
        /// <param name="appts">The appointments to add.</param>
        public void AddAppointments(string filePath, IEnumerable<Appointment> appts)
        {
            Writer.AddToCalendar(appts, filePath);
        }

        /// <summary>
        /// Adds an appointment to a specified calendar.
        /// </summary>
        /// <param name="filePath">The path of the calendar file to which to add the appointments.</param>
        /// <param name="appt">The appointment to add.</param>
        public void AddAppointment(string filePath, Appointment appt)
        {
            appt.Save(filePath);
        }

        /// <summary>
        /// Updates the information in an existing appointment.
        /// </summary>
        /// <param name="appt">The new version of the appointment to put in the calendar. This appointment
        /// will replace the appointment in the Calendar with the same UID.</param>
        /// <param name="filePath">The calendar file to be edited.</param>
        public void EditAppointment(string filePath, Appointment appt)
        {
            Writer.EditAppointment(appt, filePath);
        }

        /// <summary>
        /// Imports appointments from a calendar into the current calendar.
        /// </summary>
        /// <param name="importCalendar">The path of the calendar to import events from.</param>
        /// <param name="currentCalendar">The path of the file for the current calendar.</param>
        public void ImportCalendar(string importCalendar, string currentCalendar)
        {
            Writer.AddToCalendar(GetAllAppointments(importCalendar), currentCalendar);
        }

        /// <summary>
        /// Exports appointments from the current calendar to a new file.
        /// </summary>
        /// <param name="exportTarget">The file path of the new calendar to be created by the export.</param>
        /// <param name="currentCalendar">The file path of the current calendar.</param>
        public void ExportCalendar(string exportTarget, string currentCalendar)
        {
            Writer.CreateCalendar(GetAllAppointments(currentCalendar), exportTarget);
        }

        /// <summary>
        /// Imports an appoointment into a calendar.
        /// </summary>
        /// <param name="currentCalendar">The file path of the calendar to import into.</param>
        /// <param name="appt">The appointment to import.</param>
        public void Import(string currentCalendar, Appointment appt)
        {
            AddAppointment(currentCalendar, appt);
        }

        /// <summary>
        /// Exports an appointment to a calendar file.
        /// </summary>
        /// <param name="exportTarget">The file path of the calendar to export to.</param>
        /// <param name="appt">The appointment to export.</param>
        public void Export(string exportTarget, Appointment appt)
        {
            AddAppointment(exportTarget, appt);
        }

        /// <summary>
        /// Gets all windows contacts associated with the user currently logged in.
        /// </summary>
        /// <returns>A list of Attendees converted from a C4F.DevKit.Contacts.SimpleContactView object.</returns>
        /// <remarks>Use the Contacts assembly shipped with the VS Express Developer Kit. </remarks>
        public List<Attendee> GetAllWindowsContactsAsAttendees()
        {
            List<Attendee> attendees = new List<Attendee>();
            ContactManager contactMgr = new ContactManager();

            foreach (SimpleContactView contact in contactMgr.GetSimpleContactCollection())
            { 
                attendees.Add(new Attendee(contact.FormattedName,
                    !string.IsNullOrEmpty(contact.BusinessEmail) ? contact.BusinessEmail : contact.PersonalEmail1));
            }

            return attendees;
        }

        #endregion Public Methods
    }
}
